home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / START16.PAK / C0W.ASM < prev    next >
Assembly Source File  |  1997-05-06  |  13KB  |  482 lines

  1. ;[]------------------------------------------------------------[]
  2. ;|      C0W.ASM -- Start Up Code For Windows                    |
  3. ;[]------------------------------------------------------------[]
  4.  
  5. ;
  6. ;       C/C++ Run Time Library - Version 8.0
  7. ;       Copyright (c) 1991, 1997 by Borland International
  8. ;       All Rights Reserved.
  9. ; $Revision:   8.2  $
  10.  
  11.         locals
  12.  
  13. .286
  14.  
  15.         __C0__ = 1
  16. include         RULES.ASI
  17.  
  18.         ASSUME CS:_TEXT, DS:DGROUP
  19.  
  20.         public  __acrtused              ;satisfy MS for now
  21. __acrtused      equ     0
  22. IFNDEF __DPMI16__
  23.         public  __WINMAINCALL           ; used internally
  24. ENDIF
  25.         public  __INITAPPCALLED         ; used internally
  26.  
  27. IFNDEF __DPMI16__
  28. extrn           WINMAIN:DIST
  29. ENDIF
  30.  
  31. extrn           INITAPP:far
  32. extrn           INITTASK:far
  33. extrn           FATALEXIT:far
  34. extrn           WAITEVENT:far
  35. extrn           LOCKSEGMENT:far
  36. extrn           UNLOCKSEGMENT:far
  37. extrn           GETWINFLAGS:far
  38. IFDEF __LARGE__
  39. extrn           MESSAGEBOX:far
  40. ENDIF
  41. IFDEF __DPMI16__
  42.   extrn         _main:DIST
  43.   extrn         _OkToInitWindowsRTL:DIST
  44.   extrn         __abort:DIST
  45. ENDIF
  46. extrn           _exit:DIST
  47. extrn           __exit:DIST
  48. extrn           __exitbuf:DIST
  49. extrn           __exitfopen:DIST
  50. extrn           __exitopen:DIST
  51. extrn           __setupio:near                  ;required!
  52. extrn           __ExceptInit:DIST
  53.  
  54.         public __DestructorCount        ;Offset to global destructor count
  55. __DestructorCount EQU  10H
  56.         public __Exception_list         ;Offset to global exception list
  57. __Exception_list  EQU  14H
  58. NULL            segment
  59.         db      16 dup (0)              ;Windows
  60.         db       4 dup (0)              ;destructor count
  61.         db       2 dup (0)              ;exception list
  62.         db       4 dup (0)              ;exception vptr
  63.         db       6 dup (0)              ;reserved
  64.         db       2 dup (0)              ;VBX control jump vector
  65.                         ;MUST be at SS:20h
  66.         db       2 dup (0)              ;reserved
  67.         ends
  68.  
  69. _CVTSEG         segment
  70.         public __RealCvtVector
  71. __RealCvtVector label word
  72.         ends
  73.  
  74. _SCNSEG         segment
  75.         public __ScanTodVector
  76. __ScanTodVector label word
  77.         ends
  78.  
  79. _FPSEG          segment
  80.         public __FPVector
  81. __FPVector      dd      0
  82.         ends
  83.  
  84. _DATA           segment
  85.         public _errno
  86. _errno          dw      0
  87.         public __protected
  88. __protected     dw      0
  89.         public __8086
  90. __8086          dw      0
  91.         public __8087
  92. __8087          dw      0
  93.         public __psp
  94. __psp           dw      0
  95.         public __hInstance
  96. __hInstance     dw      0
  97.         public __hPrev
  98. __hPrev         dw      0
  99.         public __pszCmdline
  100. __pszCmdline    dw      0
  101.         public __cmdShow
  102. __cmdShow       dw      0
  103.         public __version
  104. __version       label word
  105.         public __osversion
  106. __osversion     label word
  107.         public __osmajor
  108. __osmajor       db      0
  109.         public __osminor
  110. __osminor       db      0
  111.         public __osmode         ;Used for OS/2 protected mode by MS,
  112. __osmode        db      0               ;  currently set to 0 under Windows
  113.         public __WinAllocFlag   ;Used by malloc to get additional flags
  114. __WinAllocFlag  dw      0               ;  to pass to GlobalAlloc (for DLL use)
  115.         public __LockWIN87EM    ;Used do lock down WIN87EM to avoid
  116. __LockWIN87EM   dw      1               ;  DLL unload ordering problem
  117.         public  __abend
  118. __abend         dw      0               ;Signals abnormal end, don't run destructors etc.
  119.  
  120. IFDEF __DPMI16__
  121.   extrn         __C0environ:dword
  122.   extrn         __C0argv:dword
  123.   extrn         __C0argc:word
  124. ENDIF
  125.  
  126. CopyRight       db      'Borland C++ - Copyright 1995 Borland Intl.',0
  127.  
  128. IFDEF __LARGE__
  129. CGFailMessage    db    'CodeGuard cannot be run with multiple processes',0
  130. CGMessageTitle    db    'CodeGuard Message',0
  131. CGFail        dw    0
  132. ENDIF
  133.  
  134. IFDEF __DPMI16__
  135. DPMI16Error_s   db      'This DPMI16 application was linked incorrectly and'
  136.         db      ' will fail.',10,13,'$'
  137. ENDIF
  138.         ends
  139.  
  140. _TEXT           segment
  141.  
  142. Main            proc near
  143. IFDEF __LARGE__
  144.         jmp    @@Start
  145.  
  146.         db    'CGINITCB'    ; signature
  147.         dw    offset CGFail    ; offset in DGROUP of status word
  148. ENDIF
  149. @@Start:
  150.  
  151. ;Windows initialization.  Sets up registers and stack.
  152.  
  153. IFDEF   __DPMI16__
  154.         mov     ax, seg DGROUP
  155.         mov     ds, ax
  156. ENDIF
  157.         push    bx cx es
  158.         xor     ax,ax
  159.         push    ax
  160.         call    __ExceptInit
  161.         pop     ax
  162.         pop     es cx bx
  163.  
  164.         ;INITTASK returns:
  165.         ;  'Failure:
  166.         ;    AX = zero if it failed
  167.         ;  Success:
  168.         ;    AX = 1
  169.         ;    CX = stack limit
  170.         ;    DX = cmdShow parameter to CreateWindow
  171.         ;    ES:BX = -> DOS format command line (ES = PSP address)
  172.         ;    SI = hPrevinstance
  173.         ;    DI = hinstance
  174.         call    INITTASK
  175.         or      ax,ax
  176.         jnz     @@OK
  177.         jmp     @@Fail
  178. @@OK:           mov     word ptr ss:[__Exception_list], -1
  179.         mov     __psp,es
  180.         mov     word ptr __pszCmdline,bx
  181.         mov     __hPrev,si
  182.         mov     __hInstance,di
  183.         mov     __cmdShow,dx
  184.  
  185. IF LDATA EQ false
  186.         mov     ax,-1
  187.         push    ax
  188.         call    LOCKSEGMENT
  189. ENDIF
  190.  
  191. ;Clear _BSS, uninitialized data area
  192.  
  193. IFNDEF  __HUGE__
  194.         xor     ax, ax
  195.         push    ds
  196.         pop     es
  197.         mov     di,offset DGROUP:BeginBSS
  198.         mov     cx,offset DGROUP:EndBSS
  199.         sub     cx,di
  200.         cld
  201.         rep
  202.         stosb
  203. ENDIF
  204.  
  205. ;Init the Windows App
  206.  
  207.         xor     ax,ax
  208.         push    ax
  209.         call    WAITEVENT
  210.         push    __hInstance
  211.         call    INITAPP
  212. __INITAPPCALLED:
  213.  
  214. IFDEF __LARGE__
  215. ;Check whether CodeGuard detected multiple clients
  216.         cmp    CGFail,0
  217.         je    @@TestInit
  218. ;If so then display message and fail initializaion
  219.         pusha
  220.         call    MESSAGEBOX pascal, 0, ds offset CGFailMessage, ds offset CGMessageTitle, 1010h ; MB_ICONSTOP | MB_SYSTEMMODAL
  221.         popa
  222.         xor    ax,ax
  223. ENDIF
  224.  
  225. ;Test whether INITAPP suceeded
  226. @@TestInit:    or      ax,ax
  227.         jnz     @@InitOK
  228.         jmp     @@Fail
  229. @@InitOK:
  230.  
  231. ;Determine DOS version
  232.  
  233.         mov     ah, 30h
  234.         int     21h
  235.         mov     __version, ax   ; save minor and major revision
  236.  
  237. ;Determine whether we are in protected mode
  238.  
  239.         call    GETWINFLAGS
  240.         test    ax,1            ; WF_PMODE = 1
  241.         jz      @@realmode      ; Note:  GETWINFLAGS returns a long,
  242.                     ; so if WF_PMODE changed it could be
  243.                     ; in the high word.
  244.         mov     __protected, 8  ; Eight is for convenience.
  245. @@realmode:
  246.  
  247. ;Test for 8086/8087 presence
  248.  
  249.         test    ax,0400h        ; WF_8087 = 0x0400
  250.         jz      @@no8087
  251.         mov     __8087, 1
  252. @@no8087:
  253.         and     ax,08h+04h+02h  ; WF_CPU486|WF_CPU386|WF_CPU286
  254.         shr     ax,1            ; Convert to 4 or 2 or 1 or 0
  255.         test    ax,0004h        ; Have 4, 486 done
  256.         jnz     @@NoAdjust
  257.         or      ax,ax           ; Have 0, 8086 done
  258.         jz      @@NoAdjust
  259.         inc     ax              ; Have 2 or 1, need 3 or 2
  260. @@NoAdjust:
  261.         mov     __8086,ax       ; Set CPU Type
  262.  
  263.  
  264. IFDEF  __DPMI16__
  265. ;
  266. ; Here we attempt to prevent an early death caused by linking
  267. ; the libs in the wrong order
  268. ;
  269.         call    _OkToInitWindowsRTL
  270.         or      ax, ax
  271.         jnz     DPMI16Error
  272. ENDIF
  273.  
  274. ;Call our initialization functions, including C++ static constructors.
  275.  
  276.         mov     ax,ds
  277.         mov     es,ax
  278.         mov     si,offset DGROUP:InitStart      ;si = start of table
  279.         mov     di,offset DGROUP:InitEnd        ;di = end of table
  280.         call    Initialize
  281.  
  282. IFDEF __DPMI16__
  283. ;Set up and call _main for DPMI16 application
  284.  
  285.         push    word ptr [__C0environ+2]
  286.         push    word ptr [__C0environ]
  287.         push    word ptr [__C0argv+2]
  288.         push    word ptr [__C0argv]
  289.         push    [__C0argc]
  290.         call    _main
  291. ELSE
  292. ;Set up and call WinMain for Windows application
  293.         push    __hInstance
  294.         push    __hPrev
  295.         push    __psp
  296.         push    word ptr __pszCmdline
  297.         push    __cmdShow
  298. __WINMAINCALL:  call    WINMAIN
  299. ENDIF
  300.         push    ax      ; Push return value
  301.  
  302.         cmp     __abend, 0
  303.         jne     @@abnormalexit
  304.         call    _exit   ; Normal exit
  305. @@abnormalexit: call    __exit  ; Abnormal exit, don't call destructors etc.
  306.  
  307. IFDEF  __DPMI16__
  308. DPMI16Error:
  309.         mov     ah, 9
  310.         mov     dx, offset DPMI16Error_s
  311.         int     21h
  312.         call    __abort
  313. ENDIF
  314. ;---------------------------------------------------------------------------
  315. ;       _cleanup()      call all #pragma exit cleanup routines.
  316. ;       _checknull()    check for null pointer zapping copyright message
  317. ;       _terminate(int) exit program with error code
  318. ;       _restorezero()  restore interrupt vectors
  319. ;
  320. ;       These functions are called by exit(), _exit(), _cexit(),
  321. ;       and _c_exit().
  322. ;---------------------------------------------------------------------------
  323.  
  324. ;       Call cleanup routines
  325.  
  326. __cleanup       PROC    DIST
  327.         PUBLIC  __cleanup
  328.  
  329.         mov     ax,ds
  330.         mov     es,ax
  331.         push    si
  332.         push    di
  333.         mov     si,offset DGROUP:ExitStart
  334.         mov     di,offset DGROUP:ExitEnd
  335.         call    Cleanup
  336.         pop     di
  337.         pop     si
  338.         ret
  339. __cleanup       ENDP
  340.  
  341. ;       Check for null pointers before exit.  NO-OP on Windows.
  342.  
  343. __checknull     PROC    DIST
  344.         PUBLIC  __checknull
  345.         ret
  346. __checknull     ENDP
  347.  
  348. ;       Restore grabbed interrupt vectors.  NO-OP on Windows.
  349.  
  350. __restorezero     PROC    DIST
  351.         PUBLIC  __restorezero
  352.         ret
  353. __restorezero     ENDP
  354.  
  355. ;       Exit to DOS
  356.  
  357. __terminate     PROC    DIST
  358.         PUBLIC  __terminate
  359.  
  360. IF LDATA EQ false
  361.         mov     ax,-1
  362.         push    ax
  363.         call    UNLOCKSEGMENT
  364. ENDIF
  365.         mov     bp,sp
  366.         mov     al,[bp+cPtrSize]
  367.         mov     ah,4ch                  ;exit
  368.         int     21h
  369. __terminate     ENDP
  370.  
  371. @@Fail:         mov     al,0ffh
  372.         push    ax
  373.         call    _exit
  374.  
  375.         mov     ah,4ch                  ;exit
  376.         int     21h
  377.         endp
  378.  
  379. ;       Return default data segment in AX
  380.  
  381. __GetDGROUP     PROC    FAR
  382.         PUBLIC  __GetDGROUP
  383.         mov     ax, ss
  384.         ret
  385.         endp
  386.  
  387. ;------------------------------------------------------------------
  388. ;  Loop through a startup/exit (SE) table,
  389. ;  calling functions in order of priority.
  390. ;  ES:SI is assumed to point to the beginning of the SE table
  391. ;  ES:DI is assumed to point to the end of the SE table
  392. ;  First 64 priorities are reserved by Borland
  393. ;------------------------------------------------------------------
  394. PNEAR           EQU     0
  395. PFAR            EQU     1
  396. NOTUSED         EQU     0ffh
  397.  
  398. SE              STRUC
  399. calltype        db      ?                       ; 0=near,1=far,ff=not used
  400. priority        db      ?                       ; 0=highest,ff=lowest
  401. addrlow         dw      ?
  402. addrhigh        dw      ?
  403. SE              ENDS
  404.  
  405. Initialize      proc near
  406. @@Start:        mov     ax,100h                 ;start with lowest priority
  407.         mov     dx,di                   ;set sentinel to end of table
  408.         mov     bx,si                   ;bx = start of table
  409.  
  410. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  411.         je      @@EndOfTable            ;yes, exit the loop
  412.         cmp     es:[bx.calltype],NOTUSED;check the call type
  413.         je      @@Next
  414.         mov     cl, es:[bx.priority]    ;move priority to CX
  415.         xor     ch, ch
  416.         cmp     cx,ax                   ;check the priority
  417.         jae     @@Next                  ;too high?  skip
  418.         mov     ax,cx                   ;keep priority
  419.         mov     dx,bx                   ;keep index in dx
  420. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  421.         jmp     @@TopOfTable
  422.  
  423. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  424.         je      @@Done                  ;yes, quit
  425.         mov     bx,dx                   ;bx = highest priority item
  426.         cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  427.         mov     es:[bx.calltype],NOTUSED;wipe the call type
  428.         push    es                      ;save es
  429.         je      @@NearCall
  430.  
  431. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  432.         pop     es                      ;restore es
  433.         jmp     short @@Start
  434.  
  435. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  436.         pop     es                      ;restore es
  437.         jmp     short @@Start
  438.  
  439. @@Done:         ret
  440.         endp
  441.  
  442. Cleanup         proc near
  443. @@Start:        mov     ah,0                    ;start with highest priority
  444.         mov     dx,di                   ;set sentinel to end of table
  445.         mov     bx,si                   ;bx = start of table
  446.  
  447. @@TopOfTable:   cmp     bx,di                   ;and the end of the table?
  448.         je      @@EndOfTable            ;yes, exit the loop
  449.         cmp     es:[bx.calltype],NOTUSED;check the call type
  450.         je      @@Next
  451.         cmp     es:[bx.priority],ah     ;check the priority
  452.         jb      @@Next                  ;too low?  skip
  453.         mov     ah,es:[bx.priority]     ;keep priority
  454.         mov     dx,bx                   ;keep index in dx
  455. @@Next:         add     bx,SIZE SE              ;bx = next item in table
  456.         jmp     @@TopOfTable
  457.  
  458. @@EndOfTable:   cmp     dx,di                   ;did we exhaust the table?
  459.         je      @@Done                  ;yes, quit
  460.         mov     bx,dx                   ;bx = highest priority item
  461.         cmp     es:[bx.calltype],PNEAR  ;is it near or far?
  462.         mov     es:[bx.calltype],NOTUSED;wipe the call type
  463.         push    es                      ;save es
  464.         je      @@NearCall
  465.  
  466. @@FarCall:      call    DWORD PTR es:[bx.addrlow]
  467.         pop     es                      ;restore es
  468.         jmp     short @@Start
  469.  
  470. @@NearCall:     call    WORD PTR es:[bx.addrlow]
  471.         pop     es                      ;restore es
  472.         jmp     short @@Start
  473.  
  474. @@Done:         ret
  475.         endp
  476.  
  477.         ends
  478.  
  479.         end Main
  480.